//
//  IMTCANMessage.m
//  ROCOMO
//
//  Created by Kyle Sun on 7/25/16.
//  Copyright © 2016 ROCOMO. All rights reserved.
//

#import "IMTCANMessage.h"
#import "IMTCANMessageCoder.h"

const u_int8_t kIMTCANMessageExtendedDataLength1 = 254;
const u_int8_t kIMTCANMessageStandardDataLength1 = 8;
const u_int8_t kIMTCANMessageDefaultChannel = 5;
const u_int8_t kIMTCANMessageStandardFrameLength = 16;

@interface IMTCANMessage ()

@property (nonatomic, readwrite, assign) IMTCANMessageBody body;
@property (nonatomic, readwrite, strong) NSData *extra;
@property (nonatomic, readwrite, strong) NSString *key;

@property (nonatomic, assign) BOOL isStandard;
@property (nonatomic, assign) BOOL isNew;


@end

@implementation IMTCANMessage

- (id)init {
    NSAssert(YES, @"use initWithBody:extra: instead.");
    return nil;
}

- (instancetype)initWithBody:(IMTCANMessageBody)body extra:(NSData *)extra {
    self = [super init];
    if (self) {
        self.isNew = NO;
        self.body = body;
        self.extra = extra;
    }
    return self;
}

// r0 生成消息
- (instancetype)initWithCmd:(unsigned char)cmdID otherID:(unsigned char)otherID dev:(unsigned char)dev extra:(NSData *)extra {
    self = [super init];
    if (self) {
        self.isNew = NO;
        IMTCANMessageBody body;
        /*
         1、 当功能码为7、8、9、10时为固件升级，功能拓展码表示操作的结果
         2、 功能码= 0x01:读取车辆信息，0x03:写入车辆信息，0x05:读取黑匣子记录。0x06:获取车辆序列号sn
         */
        if (cmdID == 7 || cmdID == 9 || cmdID == 10) {
            body.cid = cmdID;
        }else if (cmdID == 8){
            /// 当发送升级文件数据时下标是data的第一个元素
            Byte codeKeyByteAry[extra.length];
            for (int i = 0 ; i < extra.length; i++) {
                NSData *idata = [extra subdataWithRange:NSMakeRange(i, 1)];
                codeKeyByteAry[i] =((Byte*)[idata bytes])[0];
            }
            body.cid = codeKeyByteAry[0];
        }else if (cmdID == 5){ /// 获取黑匣子记录
            body.cid = otherID;
        }else {
            body.cid = otherID;
        }
        self.body = body;
        self.extra = extra;

    }
    return self;
}

/*
 * 消息的newKey , 专用组与标准组采用不同的定义规则。- 根据format确定newKey的拼接方式
 * （最后再拼接上当前时间戳的后四位，从而确保newKey的唯一性： 但是未能保证发送消息时的newKey与收到数据时的newKey的一致性 -- 解决方案：使用当前时间戳的后四位作为消息的tab参数，需要用到tab的直接使用tab）
 * 标准组：dataType + tab + source + target + channel & 0x7f + property
 * 专用组：dataType + tab + source + target + cmd & 0x3f
 * 后改为source和target不参与key的生成，datatype也不参与生成。
 */

- (NSString *)key {
    if (!_key) {
        if (self.isNew) {
            NSString *newKeyStr = @"";
//            newKeyStr = [newKeyStr stringByAppendingString:[NSString stringWithFormat:@"%x",self.newBody.format.dataType]];
            if (self.newBody.format.isHasTab) {
                newKeyStr = [newKeyStr stringByAppendingString:[NSString stringWithFormat:@"%x_",self.newBody.tab]];
            }
            
            if (self.isStandard) {
                if (self.newBody.format.dataType == 1) {
                    newKeyStr = [newKeyStr stringByAppendingString:[NSString stringWithFormat:@"%x%x",self.StandardData.channel & 0x7f,self.StandardData.property]];
                }
                if (self.newBody.format.dataType == 2) {
                    newKeyStr = [newKeyStr stringByAppendingString:[NSString stringWithFormat:@"%x%x",self.StandardData.channel & 0x7f,self.StandardData.property]];
                }
                if (self.newBody.format.dataType == 3) {
                    newKeyStr = [newKeyStr stringByAppendingString:[NSString stringWithFormat:@"%x%x",self.StandardData.channel & 0x7f,self.StandardData.property]];
                }
                _key = newKeyStr;
            }else {
                if (self.newBody.format.dataType == 4) {
                    newKeyStr = [newKeyStr stringByAppendingString:[NSString stringWithFormat:@"%x",self.DedicatedData.cmd & 0x3fffffff]];
                }
                if (self.newBody.format.dataType == 5) {
                    newKeyStr = [newKeyStr stringByAppendingString:[NSString stringWithFormat:@"%x",self.DedicatedData.cmd & 0x3fffffff]];
                }
                if (self.newBody.format.dataType == 6) {
                    newKeyStr = [newKeyStr stringByAppendingString:[NSString stringWithFormat:@"%x",self.DedicatedData.cmd & 0x3fffffff]];
                }
                _key = newKeyStr;
            }

        }else {
            _key = [NSString stringWithFormat:@"%0x", _body.cid];
        }
    }
    return _key;
}

- (NSData *)encodedData {
    IMTCANMessageCoder *coder = [[IMTCANMessageCoder alloc] init];
    return [coder dataFromMessage:self];
}


// 新协议
// 标准组
- (instancetype)initWithBody:(IM_NewMessageBody)newBody StandardData:(IM_NewStandardDataFormat)StandardData data:(NSData *)data {
    self = [super init];
    if (self) {
        self.isNew = YES;
        self.newBody = newBody;
        self.StandardData = StandardData;
        self.para = data;
        self.isStandard = YES;
    }
    return self;
}

// 专用组
- (instancetype)initWithBody:(IM_NewMessageBody)newBody DedicatedData:(IM_NewDedicatedDataFormat)DedicatedData data:(NSData *)data {
    self = [super init];
    if (self) {
        self.isNew = YES;
        self.newBody = newBody;
        self.DedicatedData = DedicatedData;
        self.para = data;
        self.isStandard = NO;
    }
    return self;
}

// 自由组
- (instancetype)initWithBody:(IM_NewMessageBody)newBody data:(NSData *)data {
    self = [super init];
    if (self) {
        self.isNew = YES;
        self.newBody = newBody;
        self.para = data;
        self.isStandard = NO;
    }
    return self;
}

@end

